using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Services;
using System.Diagnostics;

// This class is used to Intercept marshal, unmarshal, and disconnect events for an object.
public class TrackingHandler : ITrackingHandler
{
	// Called when the tracked object is marshaled.

	[System.Security.Permissions.SecurityPermissionAttribute(
	 System.Security.Permissions.SecurityAction.LinkDemand,
	 Flags = System.Security.Permissions.SecurityPermissionFlag.Infrastructure)]
	public void MarshaledObject(Object obj, ObjRef objRef)
	{
		// Notify the user of the marshal event.
		Trace.WriteLine(string.Format("Tracking: An instance of {0} was marshaled.", obj.ToString()));

		// Print the channel information.
		if (objRef.ChannelInfo != null)
		{
			// Iterate over ChannelData.
			foreach (object data in objRef.ChannelInfo.ChannelData)
			{
				if (data is ChannelDataStore)
				{
					// Print the URIs from the ChannelDataStore objects.
					string[] uris = ((ChannelDataStore)data).ChannelUris;
					foreach (string uri in uris)
						Trace.WriteLine(string.Format("ChannelUri: {0}", uri));
				}
			}
		}

		// Print the envoy information.
		if (objRef.EnvoyInfo != null)
			Trace.WriteLine(string.Format("EnvoyInfo: {0}", objRef.EnvoyInfo.ToString()));

		// Print the type information.
		if (objRef.TypeInfo != null)
		{
			Trace.WriteLine(string.Format("TypeInfo: {0}", objRef.TypeInfo.ToString()));
			Trace.WriteLine(string.Format("TypeName: {0}", objRef.TypeInfo.TypeName));
		}

		// Print the URI.
		if (objRef.URI != null)
			Trace.WriteLine(string.Format("URI: {0}", objRef.URI.ToString()));
	}

	// Called when the tracked object is unmarshaled.
	[System.Security.Permissions.SecurityPermissionAttribute(
	 System.Security.Permissions.SecurityAction.LinkDemand,
	 Flags = System.Security.Permissions.SecurityPermissionFlag.Infrastructure)]
	public void UnmarshaledObject(Object obj, ObjRef objRef)
	{
		Trace.WriteLine(string.Format("Tracking: An instance of {0} was unmarshaled.", obj.ToString()));
	}

	// Called when the tracked object is disconnected.
	[System.Security.Permissions.SecurityPermissionAttribute(
	 System.Security.Permissions.SecurityAction.LinkDemand,
	 Flags = System.Security.Permissions.SecurityPermissionFlag.Infrastructure)]
	public void DisconnectedObject(Object obj)
	{
		Trace.WriteLine(string.Format("Tracking: An instance of {0} was disconnected.", obj.ToString()));
	}
}